﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;

namespace Kinect_MediaPlayer
{
    public partial class CustomScrollBar : UserControl
    {
        [DllImport("user32.dll")]
        protected static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam);

        protected const int WM_VSCROLL = 0x115;

        protected Timer ScrollTimer;
        int scrollCount = 0;

        private string BaseName;
        private ScrollType ScrollType;

        private bool mouseDown;
        private bool mouseHover;
        private int BarWidth = 730;
        private int endWidth = 32;

        protected Control ScrollControl;
        protected ScrollEventType ScrollAmount;
        protected ScrollEventType FullScrollAmount;
        private bool UseCounter;

        public const string ImagesFolder = @"..\..\Images\";
        public const string InterfaceImagesFolder = ImagesFolder + @"Scroll\";

        public static Image ScrollBarLeft = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBarLeft.png", FileMode.Open, FileAccess.Read));
        public static Image ScrollBarRight = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBarRight.png", FileMode.Open, FileAccess.Read));
        public static Image ScrollBarCenter = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBar.png", FileMode.Open, FileAccess.Read));
        public static Image ArrowUp = Image.FromStream(new FileStream(InterfaceImagesFolder + "upArrow.png", FileMode.Open, FileAccess.Read));
        public static Image ArrowDown = Image.FromStream(new FileStream(InterfaceImagesFolder + "downArrow.png", FileMode.Open, FileAccess.Read));

        public static Image ScrollBarLeft_Down = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBarLeft_down.png", FileMode.Open, FileAccess.Read));
        public static Image ScrollBarRight_Down = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBarRight_down.png", FileMode.Open, FileAccess.Read));
        public static Image ScrollBarCenter_Down = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBar_down.png", FileMode.Open, FileAccess.Read));
        public static Image ArrowUp_Down = Image.FromStream(new FileStream(InterfaceImagesFolder + "upArrow_down.png", FileMode.Open, FileAccess.Read));
        public static Image ArrowDown_Down = Image.FromStream(new FileStream(InterfaceImagesFolder + "downArrow_down.png", FileMode.Open, FileAccess.Read));

        public static Image ScrollBarLeft_Hover = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBarLeft_hover.png", FileMode.Open, FileAccess.Read));
        public static Image ScrollBarRight_Hover = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBarRight_hover.png", FileMode.Open, FileAccess.Read));
        public static Image ScrollBarCenter_Hover = Image.FromStream(new FileStream(InterfaceImagesFolder + "ScrollBar_hover.png", FileMode.Open, FileAccess.Read));
        public static Image ArrowUp_Hover = Image.FromStream(new FileStream(InterfaceImagesFolder + "upArrow_hover.png", FileMode.Open, FileAccess.Read));
        public static Image ArrowDown_Hover = Image.FromStream(new FileStream(InterfaceImagesFolder + "downArrow_hover.png", FileMode.Open, FileAccess.Read));

        public CustomScrollBar(string baseName, Control scrollControl, ScrollType scrollType, int width, int interval, bool useCounter)
        {
            InitializeScrollBar(baseName, scrollControl, scrollType, width, interval, useCounter);
        }

        public CustomScrollBar(string baseName, Control scrollControl, int width, ScrollType scrollType)
        {
            InitializeScrollBar(baseName, scrollControl, scrollType, width, 7, true);
        }

        public CustomScrollBar(string baseName, Control scrollControl, ScrollType scrollType)
        {
            InitializeScrollBar(baseName, scrollControl, scrollType, 730, 7, true);
        }

        public void InitializeScrollBar(string baseName, Control scrollControl, ScrollType scrollType, int width, int interval, bool useCounter)
        {
            InitializeComponent();
            this.AutoScaleMode = AutoScaleMode.Dpi;

            BaseName = baseName;
            BarWidth = width;
            ScrollType = scrollType;
            

            InitializeScrollTimers(interval);

            ScrollControl = scrollControl;
            ScrollAmount = scrollType == ScrollType.Down ? ScrollEventType.SmallIncrement : ScrollEventType.SmallDecrement;
            FullScrollAmount = scrollType == ScrollType.Down ? ScrollEventType.Last : ScrollEventType.First;
            UseCounter = useCounter;

            this.Size = new Size(BarWidth, this.Size.Height);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Image left = mouseDown ? ScrollBarLeft_Down: (mouseHover ? ScrollBarLeft_Hover : ScrollBarLeft);
            Image right = mouseDown ? ScrollBarRight_Down : (mouseHover ? ScrollBarRight_Hover : ScrollBarRight);
            Image center = mouseDown ? ScrollBarCenter_Down : (mouseHover ? ScrollBarCenter_Hover : ScrollBarCenter);

            e.Graphics.DrawImage(left, 0, 0, endWidth, 35);
            e.Graphics.DrawImage(center, endWidth, 0, BarWidth - (endWidth * 2) + BarWidth/100, 35);
            e.Graphics.DrawImage(right, BarWidth - endWidth, 0, endWidth, 35);

            Image image = ScrollType == ScrollType.Up 
                ? (mouseDown ? ArrowUp_Down: (mouseHover ? ArrowUp_Hover : ArrowUp))
                : (mouseDown ? ArrowDown_Down: (mouseHover ? ArrowDown_Hover : ArrowDown));
            e.Graphics.DrawImage(image, this.Width / 2 - 31 / 2, this.Height / 2 - 24 / 2, 31, 24);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            mouseDown = true;
            this.Refresh();
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            mouseDown = false;
            this.Refresh();
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            Hover();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            HoverEnd();
        }

        protected override void OnClick(EventArgs e)
        {
            SendMessage(ScrollControl.Handle, (uint)WM_VSCROLL, (System.UIntPtr)FullScrollAmount, (System.IntPtr)0);
        }

        private void InitializeScrollTimers(int interval)
        {
            ScrollTimer = new Timer();
            ScrollTimer.Interval = interval;
            ScrollTimer.Tick += new EventHandler(ScrollTimer_Tick);
        }

        protected void ScrollTimer_Tick(object sender, EventArgs args)
        {
            scrollCount += 7;

            if (!UseCounter || scrollCount > 100)
                SendMessage(ScrollControl.Handle, (uint)WM_VSCROLL, (System.UIntPtr)ScrollAmount, (System.IntPtr)0);
        }

        //public functions
        public void Hover()
        {
            mouseHover = true;
            this.Refresh();
            ScrollTimer.Start();
        }

        public void HoverEnd()
        {
            mouseHover = false;
            this.Refresh();
            ScrollTimer.Stop();
            scrollCount = 0;
        }

        public void ResizeScrollBar(int width)
        {
            BarWidth = width;
            this.Size = new Size(BarWidth, this.Size.Height);
            this.Refresh();
        }

        public void ResizeScrollBar(int width, int height)
        {
            BarWidth = width;
            this.Size = new Size(BarWidth, this.Size.Height);
            this.Refresh();
        }
    }
}
